package edu.ccut.saturn.component.impl.node;

import java.util.List;

import edu.ccut.saturn.component.ILogger;
import edu.ccut.saturn.component.ILogicContext;
import edu.ccut.saturn.component.INodeInfo;
import edu.ccut.saturn.component.IParameterContext;
import edu.ccut.saturn.component.IParameterInfo;
import edu.ccut.saturn.component.SaturnLoggerManager;
import edu.ccut.saturn.component.xml.ISaturnElement;

/**
 * INodeInfo 的抽象实现类。抽取并实现了所有结点的共性部分--包括公共属性和方法。 其它结点需要扩展AbstractNodeInfo。
 * <p>
 * 定义了结点的如下公共属性：
 * <li>id：结点的唯一标识
 * <li>name：结点名称
 * <li>nextId：下一结点标识
 * <li>description：描述信息
 * <li>parameters：参数信息列表
 * <li>定义了大于号、小于号的转译字符。数据结点和转移结点需要把大于号小于号及转译字符间进行转换。
 * 
 * @author 谷钰
 * @version 1.0 2008.8.15
 * 
 * @see INodeInfo
 * @see IParameterInfo
 * @see ILogicContext
 * 
 */

public abstract class AbstractNodeInfo implements INodeInfo {

	private static final String LOGGER_KEY_BUNDLE_RUNTIME = SaturnLoggerManager.LOGGER_KEY_COMPONENT_RUNTIME;

	// TODO:大于号、小于号的转译字符的常量是否应该写在这
	protected static final String LARGE_THAN = "__lt__";

	protected static final String LESS_THAN = "__le__";
	// TODO:是否有必要是静态的？在什么时候初始化
	protected static ILogger logger = SaturnLoggerManager.getInstance()
			.getSaturnLogger(LOGGER_KEY_BUNDLE_RUNTIME);

	private String id;

	private String name;

	private String nextId;

	private String description;

	private List<IParameterInfo> parameters;

	private String x;

	private String y;

	private String nodeType;

	public AbstractNodeInfo(String id, String name, String description,
			String nextId, List<IParameterInfo> parameters, String x, String y,
			String nodeType) {

		this.id = id;
		this.name = name;
		this.description = description;
		this.nextId = nextId;
		this.parameters = parameters;
		this.x = x;
		this.y = y;
		this.nodeType = nodeType;
	}

	public String getId() {
		return id;
	}

	public String getKey() {
		return null;
	}

	public String getX() {
		return x;
	}

	public void setX(String x) {
		this.x = x;
	}

	public String getY() {
		return y;
	}

	public void setY(String y) {
		this.y = y;
	}

	public String getNodeType() {
		return nodeType;
	}

	public void setNodeType(String nodeType) {
		this.nodeType = nodeType;
	}

	/**
	 * 设置结点的唯一标识。
	 * 
	 * @param id
	 *            结点的唯一标识
	 */
	public void setId(String id) {
		this.id = id;
	}

	public String getNextId() {
		return nextId;
	}

	/**
	 * 设置当前结点的下一结点的id
	 * 
	 * @param nextId
	 *            下一运行结点的id的值
	 */
	public void setNextId(String nextId) {
		this.nextId = nextId;
	}

	public List<IParameterInfo> getParameterInfos() {
		return parameters;
	}

	/**
	 * 设置结点的参数列表
	 * 
	 * @param parameters
	 */
	public void setParameterInfos(List<IParameterInfo> parameters) {
		this.parameters = parameters;
	}

	public String getName() {
		return name;
	}

	/**
	 * 设置结点的名称
	 * 
	 * @param name
	 */
	public void setName(String name) {
		this.name = name;
	}

	public String getDescription() {
		return description;
	}

	/**
	 * 设置结点的描述信息
	 * 
	 * @param description
	 */
	public void setDescription(String description) {
		this.description = description;
	}

	public void execute(ILogicContext logicContext) throws Exception {
		debugExecuteStart(logicContext);

		try {
			doExecute(logicContext);
		} finally {
			debugExecuteEnd(logicContext);
		}
	}

	public abstract void doExecute(ILogicContext logicContext) throws Exception;

	protected abstract IParameterContext createParameterContext(
			ILogicContext logicContext) throws Exception;

	public String toXmlStr() {
			ISaturnElement saturnElement = toSaturnElement();
			return saturnElement.getXMLStr();
	}

	protected void debugExecuteStart(ILogicContext logicContext) {
		if (logicContext != null) {
			logger.debug("    node-" + this.getNodeType() + "-begin : { name : '"
					+ this.getName() + "', type : '" + this.getNodeType()
					+ "', process : '" + logicContext.getId() + "'}");
		} else {
			logger.debug("    node-" + this.getNodeType() + "-start : { name : '"
					+ this.getName() + "', type : '" + this.getNodeType()+ "'}");
		}
	}

	protected void debugExecuteEnd(ILogicContext logicContext) {
		if (logicContext != null) {
			logger.debug("    node-" + this.getNodeType() + "-end : { name : '"
					+ this.getName() + "', type : '" + this.getNodeType() + "', process : '" + logicContext.getId()
					+ "'}");
		} else {
			logger.debug("    node-" + this.getNodeType() + "-end : { name : '"
					+ this.getName() + "', type : '" + this.getNodeType() + "'}");
		}
	}
}
